package org.zjt.book;
import java.io.{IOException, InputStream}
import java.net.{MalformedURLException, URL}

import scala.util.control.Breaks._

/**
 * PS: 函数后无等号（=），则不会返回值
 */
object MethodTest {


  def main(args: Array[String]): Unit = {

    //单行和多行花括号语句
    val num :Int = 0 ;
    val var1 = if(num == 0) 1 else -1   //单行语句不适用花括号
    println(var1)


    val var2 = if(num == 0) {     //多行需要用花括号
      val value = 1 ;
      value
    } else -1
    println(var2)


    val var3 = if(num == 0) {
      val value = 1
      value
    } else -1
    println(var3)


    val  var4 = if (var3 % 2 == 0) var3 else ()
    println(var4)


    println("@" * 2) //@@ 字符串*int 输出多个字符串


    //方法返回值
    var  var5 = 2
    val  var6 = if (var5 > 0) { var5 += 2 ; math.sqrt(var5) } else ()
    println(var6)


    //控制台输入输出
    val name : String = readLine("name:")
    val age :Int = readInt()
    println(name +" : "+age)


    //字符串遍历
    for (i <- "zhang") printf(" %s",i)

    println()


    //import scala.util.control.Breaks._中的breakable、break来打破循环。
    breakable {
      for (i <- "zhang") {
        print(i.toString)
        if (i.toString.contains("h")) {print(i.toString);break}
      }
    }


    //相当于A循环中嵌套着一个B循环
    println()
    for (i <- 0 to 3 ; j <- 0 to 3) printf(" %s",i*10+j)



    //相当于A循环中嵌套着一个B循环,并将A中的i变量传递给B中，作为循环条件
    println()
    for (i <- 0 to 3 ; j <- i to 3) printf(" %s",i*10+j)



    //yield的每个元素返回，并存放在一个array中。
    println()
    var var7 = for (i <- 0 to 3 ; j <- i to 3) yield i*10+j
    println(var7.mkString(","))



    //递归实现阶乘
    println()
    def fac(n:Int) :Int = if (n <= 0) 1 else n * fac(n-1)
    println(fac(3))


    /**
      *  默认参数函数、带名参数
      * ERROR :  println(decode(str="zhang","{{"))
      * PS:混合使用（带名和不带名），未命名参数必须放在第一位
      * @param str
      * @param left
      * @param right
      * @return
      */
    def decode(str :String ,left :String = "[" ,right :String = "]") :String = left + str + right
    println(decode("zhang"))
    println(decode("zhang",left = "{{"))
    println(decode("zhang","{{"))
    println(decode(str="zhang",left = "{{" ,right = "}}"))


    /**
      * 可变长参数  :Any * 变长    :_s  序列
      * PS:    1 to 3 :_* 将range转化为Seq序列
      * @param args
      * @return
      */
    def sum(args :Int *) :Int = args.sum

    println(sum(1))
    println(sum(1 to 3 :_* ))  //1 to 3 :_* 将range转化为Seq序列


    /**
      * 过程中无返回值，所以没有=，在方法实现和声明之间，但必须要花括号
      * @param s
      */
    def box(s:String){ println(s) }


    /**
      * 懒加载 lazy
      */
    lazy val words = scala.io.Source.fromFile("test.txt").mkString(",")
    println(words)




    /**
      * 异常:都是java 的类
      */
    val url ="http77s://www.baidu.com"
    var in : InputStream = null
    try {
      in= new URL(url).openStream()
    }catch {
      case ex : IOException => println("error ex:"+ex.getMessage)
      case e : MalformedURLException => println("error e:"+e.getMessage)
    }finally {
      if (in != null)
      in.close()
    }



    /**
      * 函數的_使用
      *
      */
    // TODO:  method( _:type ) 实现参数的传递(必须有type)
    def add(x:Int ,y :Int ) = x+y
    def add2 = add(_:Int , 2)
    println(add2(2))

    def pr = println(_:Int)
    pr(2)


    def  mulipty(x:Int )(y:Int) = x * y
    def  mulipty2 = mulipty(2)_

    def  mulipty3(x:Int ,y:Int) = x * y
    def  mulipty4 = mulipty3(2, _ :Int)

    println(mulipty2(22))
    println(mulipty4(22))


    // TODO: 匿名函數 callback 引用              函数后无 =，则无返回值
    def executorFunction(callback : (Int , Int) => Int) ={
      println(callback(12,232))
      1000
    }

    def sumMethod(x:Int , y:Int) = x+y
    println(executorFunction(sumMethod))




    // TODO:  嵌套函数（函数中定义函数）
    def method23(x :Int ,y :Int , z :Int): Int ={

      def innerMethod( a :Int ,b :Int) = a + b
      innerMethod(innerMethod(x,y),z)

    }
    println(method23(232,231,122))




    //  TODO: 返回函数的函数
    //  参数：一个函数   f :Int => Int
    //  返回值：一个函数 (Int ,Int) => Int
    def handMethod (f : Int => Int) :  (Int ,Int) => Int  ={
      /** 执行f，并返回一个(Int ,Int) => Int的函数*/
      def innerMethod( x:Int , y :Int) : Int = if (x > y) 0 else f(x) + innerMethod(x+1,y)
      innerMethod
    }
    handMethod( x=>x )(1,2)


  }
}
